home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Reference / FAQs on CD / C++ FAQ Lite (4⁄7) < prev    next >
Encoding:
Text File  |  1997-01-17  |  53.5 KB  |  1,491 lines  |  [TEXT/R*ch]

  1. Archive-name: C++-faq/part4
  2. Posting-Frequency: monthly
  3. Last-modified: Jan 1, 1997
  4. URL: http://www.cerfnet.com/~mpcline/c++-faq-lite/
  5.  
  6. AUTHOR: Marshall Cline / cline@parashift.com / Paradigm Shift, Inc. /
  7. One Park St. / Norwood, NY 13668 / 315-353-6100 (voice) / 315-353-6110 (fax)
  8.  
  9. COPYRIGHT: This posting is part of "C++ FAQ Lite."  The entire "C++ FAQ Lite"
  10. document is Copyright(C) 1991-96 Marshall P. Cline, Ph.D., cline@parashift.com.
  11. All rights reserved.  Copying is permitted only under designated situations.
  12. For details, see section [1].
  13.  
  14. NO WARRANTY: THIS WORK IS PROVIDED ON AN "AS IS" BASIS.  THE AUTHOR PROVIDES NO
  15. WARRANTY WHATSOEVER, EITHER EXPRESS OR IMPLIED, REGARDING THE WORK, INCLUDING
  16. WARRANTIES WITH RESPECT TO ITS MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
  17. PURPOSE.
  18.  
  19. C++-FAQ-Lite != C++-FAQ-Book: This document, C++ FAQ Lite, is not the same as
  20. the C++ FAQ Book.  The book (C++ FAQs, Cline and Lomow, Addison-Wesley) is 500%
  21. larger than this document, and is available in bookstores.  For details, see
  22. section [3].
  23.  
  24. ==============================================================================
  25.  
  26. SECTION [14]: Friends
  27.  
  28.  
  29. [14.1] What is a friend?
  30.  
  31. Something to allow your class to grant access to another class or function.
  32.  
  33. Friends can be either functions or other classes.  A class grants access
  34. privileges to its friends.  Normally a developer has political and technical
  35. control over both the friend and member functions of a class (else you may need
  36. to get permission from the owner of the other pieces when you want to update
  37. your own class).
  38.  
  39. ==============================================================================
  40.  
  41. [14.2] Do friends violate encapsulation?
  42.  
  43. If they're used properly, they actually enhance encapsulation.
  44.  
  45. You often need to split a class in half when the two halves will have different
  46. numbers of instances or different lifetimes.  In these cases, the two halves
  47. usually need direct access to each other (the two halves used to be in the same
  48. class, so you haven't increased the amount of code that needs direct access to
  49. a data structure; you've simply reshuffled the code into two classes instead of
  50. one).  The safest way to implement this is to make the two halves friends of
  51. each other.
  52.  
  53. If you use friends like just described, you'll keep private things private.
  54. People who don't understand this often make naive efforts to avoid using
  55. friendship in situations like the above, and often they actually destroy
  56. encapsulation.  They either use public data (grotesque!), or they make the data
  57. accessible between the halves via public get() and set() member functions.
  58. Having a public get() and set() member function for a private datum is OK only
  59. when the private datum "makes sense" from outside the class (from a user's
  60. perspective).  In many cases, these get()/set() member functions are almost as
  61. bad as public data: they hide (only) the name of the private datum, but they
  62. don't hide the existence of the private datum.
  63.  
  64. Similarly, if you use friend functions as a syntactic variant of a class's
  65. public: access functions, they don't violate encapsulation any more than a
  66. member function violates encapsulation.  In other words, a class's friends
  67. don't violate the encapsulation barrier: along with the class's member
  68. functions, they are the encapsulation barrier.
  69.  
  70. ==============================================================================
  71.  
  72. [14.3] What are some advantages/disadvantages of using friend functions?
  73.  
  74. They provide a degree of freedom in the interface design options.
  75.  
  76. Member functions and friend functions are equally privileged (100% vested).
  77. The major difference is that a friend function is called like f(x), while a
  78. member function is called like x.f().  Thus the ability to choose between
  79. member functions (x.f()) and friend functions (f(x)) allows a designer to
  80. select the syntax that is deemed most readable, which lowers maintenance costs.
  81.  
  82. The major disadvantage of friend functions is that they require an extra line
  83. of code when you want dynamic binding.  To get the effect of a virtual friend,
  84. the friend function should call a hidden (usually protected:) virtual[20]
  85. member function.  This is called the Virtual Friend Function Idiom[15.8].  For
  86. example:
  87.  
  88.     class Base {
  89.     public:
  90.       friend void f(Base& b);
  91.       // ...
  92.     protected:
  93.       virtual void do_f();
  94.       // ...
  95.     };
  96.  
  97.     inline void f(Base& b)
  98.     {
  99.       b.do_f();
  100.     }
  101.  
  102.     class Derived : public Base {
  103.     public:
  104.       // ...
  105.     protected:
  106.       virtual void do_f();  // "Override" the behavior of f(Base& b)
  107.       // ...
  108.     };
  109.  
  110.     void userCode(Base& b)
  111.     {
  112.       f(b);
  113.     }
  114.  
  115. The statement f(b) in userCode(Base&) will invoke b.do_f(), which is
  116. virtual[20].  This means that Derived::do_f() will get control if b is actually
  117. a object of class Derived.  Note that Derived overrides the behavior of the
  118. protected: virtual[20] member function do_f(); it does not have its own
  119. variation of the friend function, f(Base&).
  120.  
  121. ==============================================================================
  122.  
  123. [14.4] What does it mean that "friendship is neither inherited nor transitive"?
  124.  
  125. I may declare you as my friend, but that doesn't mean I necessarily trust
  126. either your kids or your friends.
  127.  * I don't necessarily trust the kids of my friends.  The privileges of
  128.    friendship aren't inherited.  Derived classes of a friend aren't necessarily
  129.    friends.  If class Fred declares that class Base is a friend, classes
  130.    derived from Base don't have any automatic special access rights to Fred
  131.    objects.
  132.  * I don't necessarily trust the friends of my friends.  The privileges of
  133.    friendship aren't transitive.  A friend of a friend isn't necessarily a
  134.    friend.  If class Fred declares class Wilma as a friend, and class Wilma
  135.    declares class Betty as a friend, class Betty doesn't necessarily have any
  136.    special access rights to Fred objects.
  137.  
  138. ==============================================================================
  139.  
  140. [14.5] Should my class declare a member function or a friend function?
  141.  
  142. Use a member when you can, and a friend when you have to.
  143.  
  144. Sometimes friends are syntactically better (e.g., in class Fred, friend
  145. functions allow the Fred parameter to be second, while members require it to be
  146. first).  Another good use of friend functions are the binary infix arithmetic
  147. operators.  E.g., aComplex + aComplex should be defined as a friend rather than
  148. a member if you want to allow aFloat + aComplex as well (member functions don't
  149. allow promotion of the left hand argument, since that would change the class of
  150. the object that is the recipient of the member function invocation).
  151.  
  152. In other cases, choose a member function over a friend function.
  153.  
  154. ==============================================================================
  155.  
  156. SECTION [15]: Input/output via <iostream.h> and <stdio.h>
  157.  
  158.  
  159. [15.1] Why should I use <iostream.h> instead of the traditional <stdio.h>?
  160.  
  161. Increase type safety, reduce errors, improve performance, allow extensibility,
  162. and provide subclassability.
  163.  
  164. printf() is arguably not broken, and scanf() is perhaps livable despite being
  165. error prone, however both are limited with respect to what C++ I/O can do.  C++
  166. I/O (using << and >>) is, relative to C (using printf() and scanf()):
  167.  * Better type safety: With <iostream.h>, the type of object being I/O'd is
  168.    known statically by the compiler.  In contrast, <stdio.h> uses "%" fields to
  169.    figure out the types dynamically.
  170.  * Less error prone: With <iostream.h>, there are no redundant "%" tokens that
  171.    have to be consistent with the actual objects being I/O'd.  Removing
  172.    redundancy removes a class of errors.
  173.  * Extensible: The C++ <iostream.h> mechanism allows new user-defined types to
  174.    be I/O'd without breaking existing code.  Imagine the chaos if everyone was
  175.    simultaneously adding new incompatible "%" fields to printf() and
  176.    scanf()?!).
  177.  * Subclassable: The C++ <iostream.h> mechanism is built from real classes such
  178.    as ostream and istream.  Unlike <stdio.h>'s FILE*, these are real classes
  179.    and hence subclassable.  This means you can have other user-defined things
  180.    that look and act like streams, yet that do whatever strange and wonderful
  181.    things you want.  You automatically get to use the zillions of lines of I/O
  182.    code written by users you don't even know, and they don't need to know about
  183.    your "extended stream" class.
  184.  
  185. ==============================================================================
  186.  
  187. [15.2] Why does my program go into an infinite loop when someone enters an
  188.        invalid input character? [NEW!]
  189.  
  190. [Recently created (on 1/97).]
  191.  
  192. For example, suppose you have the following code that reads integers from cin:
  193.  
  194.     #include <iostream.h>
  195.  
  196.     main()
  197.     {
  198.       cout << "Enter numbers separated by whitespace (use -1 to quit): ";
  199.       int i = 0;
  200.       while (i != -1) {
  201.         cin >> i;        // BAD FORM -- See comments below
  202.         cout << "You entered " << i << '\n';
  203.       }
  204.     }
  205.  
  206. The problem with this code is that it lacks any checking to see if someone
  207. entered an invalid input character.  In particuluar, if someone enters
  208. something that doesn't look like an integer (such as an 'x'), the stream cin
  209. goes into a "failed state," and all subsequent input attempts return
  210. immediately without doing anything.  In other words, the program enters an
  211. infinite loop; if 42 was the last number that was successfully read, the
  212. program will print the message You entered 42 over and over.
  213.  
  214. An easy way to check for invalid input is to move the input request from the
  215. body of the while loop into the control-expression of the while loop.  E.g.,
  216.  
  217.     #include <iostream.h>
  218.  
  219.     main()
  220.     {
  221.       cout << "Enter a number, or -1 to quit: ";
  222.       int i = 0;
  223.       while (cin >> i) {    // GOOD FORM
  224.         if (i == -1) break;
  225.         cout << "You entered " << i << '\n';
  226.       }
  227.     }
  228.  
  229. This will cause the while loop to exit either when you hit end-of-file, or when
  230. you enter a bad integer, or when you enter -1.
  231.  
  232. (Naturally you can eliminate the break by changing the while loop expression
  233. from while (cin >> i) to while ((cin >> i) && (i != -1)), but that's not really
  234. the point of this FAQ since this FAQ has to do with iostreams rather than
  235. generic structured programming guidelines.)
  236.  
  237. ==============================================================================
  238.  
  239. [15.3] How does that funky while (cin >> foo) syntax work? [NEW!]
  240.  
  241. [Recently created (on 1/97).]
  242.  
  243. See the previous FAQ[15.2] for an example of the "funky while (cin >> foo)
  244. syntax."
  245.  
  246. The expression (cin >> foo) calls the appropriate operator>> (for example, it
  247. calls the operator>> that takes an istream on the left and, if foo is of type
  248. int, an int& on the right).  The istream operator>> functions return their left
  249. argument by convention, which in this case means it will return cin.  Next the
  250. compiler notices that the returned istream is in a boolean context, so it calls
  251. the "cast" operator istream::operator bool().  I.e., in this case, it calls
  252. cin.operator bool(), just as if you had casted it explicitly such as (bool)cin
  253. or bool(cin).  (Note: if your compiler doesn't yet support the bool type,
  254. istream::operator void*() will be called instead.)
  255.  
  256. The operator bool() cast operator returns true if the stream is in a good
  257. state, or false if it's in a failed state (in the void* case, the return values
  258. will be some non-NULL pointer or the NULL pointer, respectively).  For example,
  259. if you read one too many times (e.g., if you're already at end-of-file), or if
  260. the actual info on the input stream isn't valid for the type of foo (e.g., if
  261. foo is an int and the data is an 'x' character), the stream will go into a
  262. failed state and the cast operator will return false.
  263.  
  264. The reason operator>> doesn't simply return a bool indicating whether it
  265. succeeded or failed is to support the "cascading" syntax:
  266.  
  267.       cin >> foo >> bar;
  268.  
  269. The operator>> is left-associative, which means the above is parsed as:
  270.  
  271.       (cin >> foo) >> bar;
  272.  
  273. In other words, if we replace operator>> with a normal function name such as
  274. readFrom(), this becomes the expression:
  275.  
  276.       readFrom( readFrom(cin, foo), bar);
  277.  
  278. As always, we begin evaluating at the innermost expression.  Because of the
  279. left-associativity of operator>>, this happens to be the left-most expression,
  280. cin >> foo.  This expression returns cin (more precisely, it returns a
  281. reference to its left-hand argument) to the next expression.  The next
  282. expression also returns (a reference to) cin, but this second reference is
  283. ignored since it's the outermost expression in this "expression statement."
  284.  
  285. ==============================================================================
  286.  
  287. [15.4] Why does my input seem to process past the end of file?
  288.  
  289. Because the eof state is not set until after a read is attempted past the end
  290. of file.  That is, reading the last byte from a file does not set the eof
  291. state.
  292.  
  293. For example, the following code has an off-by-one error with the count i:
  294.  
  295.     int i = 0;
  296.     while (! cin.eof()) {   // WRONG!
  297.       cin >> x;
  298.       ++i;
  299.       // Work with x ...
  300.     }
  301.  
  302. What you really need is:
  303.  
  304.     int i = 0;
  305.     while (cin >> x) {      // RIGHT!
  306.       ++i;
  307.       // Work with x ...
  308.     }
  309.  
  310. ==============================================================================
  311.  
  312. [15.5] Why is my program ignoring my input request after the first iteration?
  313.  
  314. Because the numerical extractor leaves non-digits behind in the input buffer.
  315.  
  316. If your code looks like this:
  317.  
  318.     char name[1000];
  319.     int age;
  320.  
  321.     for (;;) {
  322.       cout << "Name: ";
  323.       cin >> name;
  324.       cout << "Age: ";
  325.       cin >> age;
  326.     }
  327.  
  328. What you really want is:
  329.  
  330.     for (;;) {
  331.       cout << "Name: ";
  332.       cin >> name;
  333.       cout << "Age: ";
  334.       cin >> age;
  335.       cin.ignore(INT_MAX, '\n');
  336.     }
  337.  
  338. ==============================================================================
  339.  
  340. [15.6] How can I provide printing for my class Fred? [UPDATED!]
  341.  
  342. [Recently added note about cascading operator<< calls (on 1/97).]
  343.  
  344. Use operator overloading[13] to provide a friend[14] left-shift operator,
  345. operator<<.
  346.  
  347.     #include <iostream.h>
  348.  
  349.     class Fred {
  350.     public:
  351.       friend ostream& operator<< (ostream& o, const Fred& fred);
  352.       // ...
  353.     private:
  354.       int i_;    // Just for illustration
  355.     };
  356.  
  357.     ostream& operator<< (ostream& o, const Fred& fred)
  358.     {
  359.       return o << fred.i_;
  360.     }
  361.  
  362.     main()
  363.     {
  364.       Fred f;
  365.       cout << "My Fred object: " << f << "\n";
  366.     }
  367.  
  368. We use a friend[14] rather than a member since the Fred parameter is second
  369. rather than first.
  370.  
  371. Note that operator<< returns the stream.  This is so the output operations can
  372. be cascaded[15.3].
  373.  
  374. ==============================================================================
  375.  
  376. [15.7] How can I provide input for my class Fred? [UPDATED!]
  377.  
  378. [Recently added note about cascading operator<< calls (on 1/97).]
  379.  
  380. Use operator overloading[13] to provide a friend[14] right-shift operator,
  381. operator>>.  This is similar to the output operator[15.6], except the parameter
  382. doesn't have a const[18]: "Fred&" rather than "const Fred&".
  383.  
  384.     #include <iostream.h>
  385.  
  386.     class Fred {
  387.     public:
  388.       friend istream& operator>> (istream& i, Fred& fred);
  389.       // ...
  390.     private:
  391.       int i_;    // Just for illustration
  392.     };
  393.  
  394.     istream& operator>> (istream& i, Fred& fred)
  395.     {
  396.       return i >> fred.i_;
  397.     }
  398.  
  399.     main()
  400.     {
  401.       Fred f;
  402.       cout << "Enter a Fred object: ";
  403.       cin >> f;
  404.       // ...
  405.     }
  406.  
  407. Note that operator>> returns the stream.  This is so the input operations can
  408. be cascaded and/or used in a while loop or if statement[15.3].
  409.  
  410. ==============================================================================
  411.  
  412. [15.8] How can I provide printing for an entire hierarchy of classes?
  413.  
  414. Provide a friend[14] operator<<[15.6] that calls a protected virtual[20]
  415. function:
  416.  
  417.     class Base {
  418.     public:
  419.       friend ostream& operator<< (ostream& o, const Base& b);
  420.       // ...
  421.     protected:
  422.       virtual void print(ostream& o) const;
  423.     };
  424.  
  425.     inline ostream& operator<< (ostream& o, const Base& b)
  426.     {
  427.       b.print(o);
  428.       return o;
  429.     }
  430.  
  431.     class Derived : public Base {
  432.     protected:
  433.       virtual void print(ostream& o) const;
  434.     };
  435.  
  436. The end result is that operator<< acts as if it was dynamically bound, even
  437. though it's a friend[14] function.  This is called the Virtual Friend Function
  438. Idiom.
  439.  
  440. Note that derived classes override print(ostream&) const.  In particular, they
  441. do not provide their own operator<<.
  442.  
  443. Naturally if Base is an ABC[22.3], Base::print(ostream&) const can be declared
  444. pure virtual[22.4] using the "= 0" syntax.
  445.  
  446. ==============================================================================
  447.  
  448. [15.9] How can I "reopen" cin and cout in binary mode under DOS and/or OS/2?
  449.  
  450. This is implementation dependent.  Check with your compiler's documentation.
  451.  
  452. For example, suppose you want to do binary I/O using cin and cout.  Suppose
  453. further that your operating system (such as DOS or OS/2) insists on translating
  454. "\r\n" into "\n" on input from cin, and "\n" to "\r\n" on output to cout or
  455. cerr.
  456.  
  457. Unfortunately there is no standard way to cause cin, cout, and/or cerr to be
  458. opened in binary mode.  Closing the streams and attempting to reopen them in
  459. binary mode might have unexpected or undesirable results.
  460.  
  461. On systems where it makes a difference, the implementation might provide a way
  462. to make them binary streams, but you would have to check the manuals to find
  463. out.
  464.  
  465. ==============================================================================
  466.  
  467. [15.10] Why can't I open a file in a different directory such as "..\test.dat"?
  468.  
  469. Because "\t" is a tab character.
  470.  
  471. You should use forward slashes in your filenames, even on an operating system
  472. that uses backslashes such as DOS, Windows, OS/2, etc.  For example:
  473.  
  474.     #include <iostream.h>
  475.     #include <fstream.h>
  476.  
  477.     main()
  478.     {
  479.       #if 1
  480.         ifstsream file("../test.dat");     // RIGHT!
  481.       #else
  482.         ifstsream file("..\test.dat");     // WRONG!
  483.       #endif
  484.  
  485.       // ...
  486.     }
  487.  
  488. Remember, the backslash ("\") is used in string literals to create special
  489. characters: "\n" is a newline, "\b" is a backspace, and "\t" is a tab, "\a" is
  490. an "alert", "\v" is a vertical-tab, etc.  Therefore the file name
  491. "\version\next\alpha\beta\test.dat" is interpreted as a bunch of very funny
  492. characters; use "/version/next/alpha/beta/test.dat" instead, even on systems
  493. that use a "\" as the directory separator such as DOS, Windows, OS/2, etc.
  494.  
  495. ==============================================================================
  496.  
  497. SECTION [16]: Freestore management
  498.  
  499.  
  500. [16.1] Does delete p delete the pointer p, or the pointed-to-data *p?
  501.  
  502. The pointed-to-data.
  503.  
  504. The keyword should really be delete_the_thing_pointed_to_by.  The same abuse of
  505. English occurs when freeing the memory pointed to by a pointer in C: free(p)
  506. really means free_the_stuff_pointed_to_by(p).
  507.  
  508. ==============================================================================
  509.  
  510. [16.2] Can I free() pointers allocated with new? Can I delete pointers
  511.        allocated with malloc()?
  512.  
  513. No!
  514.  
  515. It is perfectly legal, moral, and wholesome to use malloc() and delete in the
  516. same program, or to use new and free() in the same program.  But it is illegal,
  517. immoral, and despicable to call free() with a pointer allocated via new, or to
  518. call delete on a pointer allocated via malloc().
  519.  
  520. Beware! I occasionally get e-mail from people telling me that it works OK for
  521. them on machine X and compiler Y.  That does not make it right! Sometimes
  522. people say, "But I'm just working with an array of char." Nonetheless do not
  523. mix malloc() and delete on the same pointer, or new and free() on the same
  524. pointer! If you allocated via p = new char[n], you must use delete[] p; you
  525. must not use free(p).  Or if you allocated via p = malloc(n), you must use
  526. free(p); you must not use delete[] p or delete p! Mixing these up could cause a
  527. catastrophic failure at runtime if the code was ported to a new machine, a new
  528. compiler, or even a new version of the same compiler.
  529.  
  530. You have been warned.
  531.  
  532. ==============================================================================
  533.  
  534. [16.3] Why should I use new instead of trustworthy old malloc()?
  535.  
  536. Constructors/destructors, type safety, overridability.
  537.  * Constructors/destructors: unlike malloc(sizeof(Fred)), new Fred() calls
  538.    Fred's constructor.  Similarly, delete p calls *p's destructor.
  539.  * Type safety: malloc() returns a void* which isn't type safe.  new Fred()
  540.    returns a pointer of the right type (a Fred*).
  541.  * Overridability: new is an operator that can be overridden by a class, while
  542.    malloc() is not overridable on a per-class basis.
  543.  
  544. ==============================================================================
  545.  
  546. [16.4] Can I use realloc() on pointers allocated via new?
  547.  
  548. No!
  549.  
  550. When realloc() has to copy the allocation, it uses a bitwise copy operation,
  551. which will tear many C++ objects to shreds.  C++ objects should be allowed to
  552. copy themselves.  They use their own copy constructor or assignment operator.
  553.  
  554. Besides all that, the heap that new uses may not be the same as the heap that
  555. malloc() and realloc() use!
  556.  
  557. ==============================================================================
  558.  
  559. [16.5] Do I need to check for NULL after p = new Fred()?
  560.  
  561. No! (But if you have an old compiler, you may have to force the compiler to
  562. have this behavior[16.6]).
  563.  
  564. It turns out to be a real pain to always write explicit NULL tests after every
  565. new allocation.  Code like the following is very tedious:
  566.  
  567.     Fred* p = new Fred();
  568.     if (p == NULL)
  569.       throw bad_alloc();
  570.  
  571. If your compiler doesn't support (or if you refuse to use) exceptions[17], your
  572. code might be even more tedious:
  573.  
  574.     Fred* p = new Fred();
  575.     if (p == NULL) {
  576.       cerr << "Couldn't allocate memory for a Fred" << endl;
  577.       abort();
  578.     }
  579.  
  580. Take heart.  In C++, if the runtime system cannot allocate sizeof(Fred) bytes
  581. of memory during p = new Fred(), a bad_alloc exception will be thrown.  Unlike
  582. malloc(), new never returns NULL!
  583.  
  584. Therefore you should simply write:
  585.  
  586.     Fred* p = new Fred();   // No need to check if p is NULL
  587.  
  588. However, if your compiler is old, it may not yet support this.  Find out by
  589. checking your compiler's documentation under "new".  If you have an old
  590. compiler, you may have to force the compiler to have this behavior[16.6].
  591.  
  592. ==============================================================================
  593.  
  594. [16.6] How can I convince my (older) compiler to automatically check new to see
  595.        if it returns NULL? [UPDATED!]
  596.  
  597. [Recently fixed bugs: new handlers don't take arguments, thanks to Scott Aaron;
  598. changed set_new_hanlder to set_new_handler, thanks to Peter Andersson (on
  599. 1/97).]
  600.  
  601. Eventually your compiler will.
  602.  
  603. If you have an old compiler that doesn't automagically perform the NULL
  604. test[16.5], you can force the runtime system to do the test by installing a
  605. "new handler" function.  Your "new handler" function can do anything you want,
  606. such as print a message and abort() the program, delete some objects and return
  607. (in which case operator new will retry the allocation), throw an exception,
  608. etc.
  609.  
  610. Here's a sample "new handler" that prints a message and calls abort().  The
  611. handler is installed using set_new_handler():
  612.  
  613.     #include <new.h>        // To get set_new_handler
  614.     #include <stdlib.h>     // To get abort()
  615.     #include <iostream.h>   // To get cerr
  616.  
  617.     void myNewHandler()
  618.     {
  619.       // This is your own handler.  It can do anything you want.
  620.       cerr << "Attempt to allocate memory failed!" << endl;
  621.       abort();
  622.     }
  623.  
  624.     main()
  625.     {
  626.       set_new_handler(myNewHandler);   // Install your "new handler"
  627.       // ...
  628.     }
  629.  
  630. After the set_new_handler() line is executed, operator new will call your
  631. myNewHandler() if/when it runs out of memory.  This means that new will never
  632. return NULL:
  633.  
  634.     Fred* p = new Fred();   // No need to check if p is NULL
  635.  
  636. Note: Please use this abort() approach as a last resort.  If your compiler
  637. supports exception handling[17], please consider throwing an exception instead
  638. of calling abort().
  639.  
  640. Note: If some global/static object's constructor uses new, it won't use the
  641. myNewHandler() function since that constructor will get called before main()
  642. begins.  Unfortunately there's no convenient way to guarantee that the
  643. set_new_handler() will be called before the first use of new.  For example,
  644. even if you put the set_new_handler() call in the constructor of a global
  645. object, you still don't know if the module ("compilation unit") that contains
  646. that global object will be elaborated first or last or somewhere inbetween.
  647. Therefore you still don't have any guarantee that your call of
  648. set_new_handler() will happen before any other global's constructor gets
  649. invoked.
  650.  
  651. ==============================================================================
  652.  
  653. [16.7] Do I need to check for NULL before delete p?
  654.  
  655. No!
  656.  
  657. The C++ language guarantees that delete p will do nothing if p is equal to
  658. NULL.  Since you might get the test backwards, and since most testing
  659. methodologies force you to explicitly test every branch point, you should not
  660. put in the redundant if test.
  661.  
  662. Wrong:
  663.  
  664.     if (p != NULL)
  665.       delete p;
  666.  
  667. Right:
  668.  
  669.     delete p;
  670.  
  671. ==============================================================================
  672.  
  673. [16.8] What are the two steps that happen when I say delete p?
  674.  
  675. delete p is a two-step process: it calls the destructor, then releases the
  676. memory.  The code generated for delete p looks something like this (assuming p
  677. is of type Fred*):
  678.  
  679.     // Original code: delete p;
  680.     if (p != NULL) {
  681.       p->~Fred();
  682.       operator delete(p);
  683.     }
  684.  
  685. The statement p->~Fred() calls the destructor for the Fred object pointed to by
  686. p.
  687.  
  688. The statement operator delete(p) calls the memory deallocation primitive,
  689. void operator delete(void* p).  This primitive is similar in spirit to
  690. free(void* p).  (Note, however, that these two are not interchangeable; e.g.,
  691. there is no guarantee that the two memory deallocation primitives even use the
  692. same heap!).
  693.  
  694. ==============================================================================
  695.  
  696. [16.9] In p = new Fred(), does the Fred memory "leak" if the Fred constructor
  697.        throws an exception?
  698.  
  699. No.
  700.  
  701. If an exception occurs during the Fred constructor of p = new Fred(), the C++
  702. language guarantees that the memory sizeof(Fred) bytes that were allocated will
  703. automagically be released back to the heap.
  704.  
  705. Here are the details: new Fred() is a two-step process:
  706.  
  707.  1. sizeof(Fred) bytes of memory are allocated using the primitive
  708.     void* operator new(size_t nbytes).  This primitive is similar in spirit to
  709.     malloc(size_t nbytes).  (Note, however, that these two are not
  710.     interchangeable; e.g., there is no guarantee that the two memory allocation
  711.     primitives even use the same heap!).
  712.  
  713.  2. It constructs an object in that memory by calling the Fred constructor.
  714.     The pointer returned from the first step is passed as the this parameter to
  715.     the constructor.  This step is wrapped in a try ... catch block to handle
  716.     the case when an exception is thrown during this step.
  717.  
  718. Thus the actual generated code looks something like:
  719.  
  720.     // Original code: Fred* p = new Fred();
  721.     Fred* p = (Fred*) operator new(sizeof(Fred));
  722.     try {
  723.       new(p) Fred();       // Placement new[11.10]
  724.     } catch (...) {
  725.       operator delete(p);  // Deallocate the memory
  726.       throw;               // Re-throw the exception
  727.     }
  728.  
  729. The statement marked "Placement new[11.10]" calls the Fred constructor.  The
  730. pointer p becomes the this pointer inside the constructor, Fred::Fred().
  731.  
  732. ==============================================================================
  733.  
  734. [16.10] How do I allocate / unallocate an array of things?
  735.  
  736. Use p = new T[n] and delete[] p:
  737.  
  738.     Fred* p = new Fred[100];
  739.     // ...
  740.     delete[] p;
  741.  
  742. Any time you allocate an array of objects via new (usually with the [n] in the
  743. new expression), you must use [] in the delete statement.  This syntax is
  744. necessary because there is no syntactic difference between a pointer to a thing
  745. and a pointer to an array of things (something we inherited from C).
  746.  
  747. ==============================================================================
  748.  
  749. [16.11] What if I forget the [] when deleteing array allocated via new T[n]?
  750.  
  751. All life comes to a catastrophic end.
  752.  
  753. It is the programmer's --not the compiler's-- responsibility to get the
  754. connection between new T[n] and delete[] p correct.  If you get it wrong,
  755. neither a compile-time nor a run-time error message will be generated by the
  756. compiler.  Heap corruption is a likely result.  Or worse.  Your program will
  757. probably die.
  758.  
  759. ==============================================================================
  760.  
  761. [16.12] Can I drop the [] when deleteing array of some built-in type (char,
  762.         int, etc)?
  763.  
  764. No!
  765.  
  766. Sometimes programmers think that the [] in the delete[] p only exists so the
  767. compiler will call the appropriate destructors for all elements in the array.
  768. Because of this reasoning, they assume that an array of some built-in type such
  769. as char or int can be deleted without the [].  E.g., they assume the following
  770. is valid code:
  771.  
  772.     void userCode(int n)
  773.     {
  774.       char* p = new char[n];
  775.       // ...
  776.       delete p;     // <-- ERROR! Should be delete[] p !
  777.     }
  778.  
  779. But the above code is wrong, and it can cause a disaster at runtime.  In
  780. particular, the code that's called for delete p is operator delete(void*), but
  781. the code that's called for delete[] p is operator delete[](void*).  The default
  782. behavior for the latter is to call the former, but users are allowed to replace
  783. the latter with a different behavior (in which case they would normally also
  784. replace the corresponding new code in operator new[](size_t)).  If they
  785. replaced the delete[] code so it wasn't compatible with the delete code, and
  786. you called the wrong one (i.e., if you said delete p rather than delete[] p),
  787. you could end up with a disaster at runtime.
  788.  
  789. ==============================================================================
  790.  
  791. [16.13] After p = new Fred[n], how does the compiler know there are n objects
  792.         to be destructed during delete[] p?
  793.  
  794. Short answer: Magic.
  795.  
  796. Long answer: The run-time system stores the number of objects, n, somewhere
  797. where it can be retrieved if you only know the pointer, p.  There are two
  798. popluar techniques that do this.  Both these techniques are in use by
  799. commercial grade compilers, both have tradeoffs, and neither is perfect.  These
  800. techniques are:
  801.  
  802.  3. Over-allocate the array and put n just to the left of the first Fred
  803.     object[33.4].
  804.  
  805.  4. Use an associative array with p as the key and n as the value[33.5].
  806.  
  807. ==============================================================================
  808.  
  809. [16.14] Is it legal (and moral) for a member function to say delete this?
  810.  
  811. As long as you're careful, it's OK for an object to commit suicide (delete
  812. this).
  813.  
  814. Here's how I define "careful":
  815.  
  816.  1. You must be absolutely 100% positive sure that this object was allocated
  817.     via new (not by new[], nor by placement new[11.10], nor a local object on
  818.     the stack, nor a global, nor a member of another object; but by plain
  819.     ordinary new).
  820.  
  821.  2. You must be absolutely 100% positive sure that your member function will be
  822.     the last member function invoked on this object.
  823.  
  824.  3. You must be absolutely 100% positive sure that the rest of your member
  825.     function (after the delete this line) doesn't touch any piece of this
  826.     object (including calling any other member functions or touching any data
  827.     members).
  828.  
  829.  4. You must be absolutely 100% positive sure that no one even touches the this
  830.     pointer itself after the delete this line.  In other words, you must not
  831.     examine it, compare it with another pointer, compare it with NULL, print
  832.     it, cast it, do anything with it.
  833.  
  834. Naturally the usual caveats apply in cases where your this pointer is a pointer
  835. to a base class when you don't have a virtual destructor[20.4].
  836.  
  837. ==============================================================================
  838.  
  839. [16.15] How do I allocate multidimensional arrays using new? [UPDATED!]
  840.  
  841. [Recently rewritten and expanded with a rectangular-matrix case (on 1/97).]
  842.  
  843. There are many ways to do this, depending on how flexible you want the array
  844. sizing to be.  On one extreme, if you know all the dimensions at compile-time,
  845. you can allocate multidimensional arrays statically (as in C):
  846.  
  847.     class Fred { /*...*/ };
  848.     void someFunction(Fred& fred);
  849.  
  850.     void manipulateArray()
  851.     {
  852.       const unsigned nrows = 10;  // Num rows is a compile-time constant
  853.       const unsigned ncols = 20;  // Num columns is a compile-time constant
  854.       Fred matrix[nrows][ncols];
  855.  
  856.       for (unsigned i = 0; i < nrows; ++i) {
  857.         for (unsigned j = 0; j < ncols; ++j) {
  858.           // Here's the way you access the (i,j) element:
  859.           someFunction( matrix[i][j] );
  860.  
  861.           // You can safely "return" without any special delete code:
  862.           if (today == "Tuesday" && moon.isFull())
  863.             return;     // Quit early on Tuesdays when the moon is full
  864.         }
  865.       }
  866.  
  867.       // No explicit delete code at the end of the function either
  868.     }
  869.  
  870. More commonly, the size of the matrix isn't known until run-time but you know
  871. that it will be rectangular.  In this case you need to use the heap
  872. ("freestore"), but at least you are able to allocate all the elements in one
  873. freestore chunk.
  874.  
  875.     void manipulateArray(unsigned nrows, unsigned ncols)
  876.     {
  877.       Fred* matrix = new Fred[nrows * ncols];
  878.  
  879.       // Since we used a simple pointer above, we need to be VERY
  880.       // careful to avoid skipping over the delete code.
  881.       // That's why we catch all exceptions:
  882.       try {
  883.  
  884.         // Here's how to access the (i,j) element:
  885.         for (unsigned i = 0; i < nrows; ++i) {
  886.           for (unsigned j = 0; j < ncols; ++j) {
  887.             someFunction( matrix[i*ncols + j] );
  888.           }
  889.         }
  890.  
  891.         // If you want to quit early on Tuesdays when the moon is full,
  892.         // make sure to do the delete along ALL return paths:
  893.         if (today == "Tuesday" && moon.isFull()) {
  894.           delete[] matrix;
  895.           return;
  896.         }
  897.  
  898.         // ...
  899.  
  900.       }
  901.       catch (...) {
  902.         // Make sure to do the delete when an exception is thrown:
  903.         delete[] matrix;
  904.         throw;    // Re-throw the current exception
  905.       }
  906.  
  907.       // Make sure to do the delete at the end of the function too:
  908.       delete[] matrix;
  909.     }
  910.  
  911. Finally at the other extreme, you may not even be guaranteed that the matrix is
  912. rectangular.  For example, if each row could have a different length, you'll
  913. need to allocate each row individually.  In the following function, ncols[i] is
  914. the number of columns in row number i, where i varies between 0 and nrows-1
  915. inclusive.
  916.  
  917.     void manipulateArray(unsigned nrows, unsigned ncols[])
  918.     {
  919.       Fred** matrix = new Fred*[nrows];
  920.       for (unsigned i = 0; i < nrows; ++i)
  921.         matrix[i] = new Fred[ ncols[i] ];
  922.  
  923.       // Since we used a simple pointer above, we need to be VERY
  924.       // careful to avoid skipping over the delete code.
  925.       // That's why we catch all exceptions:
  926.       try {
  927.  
  928.         // Here's how to access the (i,j) element:
  929.         for (unsigned i = 0; i < nrows; ++i) {
  930.           for (unsigned j = 0; j < ncols[i]; ++j) {
  931.             someFunction( matrix[i][j] );
  932.           }
  933.         }
  934.  
  935.         // If you want to quit early on Tuesdays when the moon is full,
  936.         // make sure to do the delete along ALL return paths:
  937.         if (today == "Tuesday" && moon.isFull()) {
  938.           for (unsigned i = nrows; i > 0; --i)
  939.             delete[] matrix[i-1];
  940.           delete[] matrix;
  941.           return;
  942.         }
  943.  
  944.         // ...
  945.  
  946.       }
  947.       catch (...) {
  948.         // Make sure to do the delete when an exception is thrown:
  949.         for (unsigned i = nrows; i > 0; --i)
  950.           delete[] matrix[i-1];
  951.         delete[] matrix;
  952.         throw;    // Re-throw the current exception
  953.       }
  954.  
  955.       // Make sure to do the delete at the end of the function too.
  956.       // Note that deletion is the opposite order of allocation:
  957.       for (i = nrows; i > 0; --i)
  958.         delete[] matrix[i-1];
  959.       delete[] matrix;
  960.     }
  961.  
  962. Note the funny use of matrix[i-1] in the deletion process.  This prevents
  963. wrap-around of the unsigned value when i goes one step below zero.
  964.  
  965. Finally, note that pointers and arrays are evil[21.5].  It is normally much
  966. better to encapsulate your pointers in a class that has a safe and simple
  967. interface.  The following FAQ[16.16] shows how to do this.
  968.  
  969. ==============================================================================
  970.  
  971. [16.16] But the previous FAQ's code is SOOOO tricky and error prone! Isn't
  972.         there a simpler way? [NEW!]
  973.  
  974. [Recently created (on 1/97).]
  975.  
  976. Yep.
  977.  
  978. The reason the code in the previous FAQ[16.15] was so tricky and error prone
  979. was that it used pointers, and we know that pointers and arrays are evil[21.5].
  980. The solution is to encapsulate your pointers in a class that has a safe and
  981. simple interface.  For example, we can define a FredMatrix class that handles a
  982. rectangular matrix so our user code will be vastly simplified when compared to
  983. the the rectangular matrix code from the previous FAQ[16.15]:
  984.  
  985.     // The code for class FredMatrix is shown below...
  986.     void someFunction(Fred& fred);
  987.  
  988.     void manipulateArray(unsigned nrows, unsigned ncols)
  989.     {
  990.       FredMatrix matrix(nrows, ncols);   // Construct a FredMatrix called matrix
  991.  
  992.       for (unsigned i = 0; i < nrows; ++i) {
  993.         for (unsigned j = 0; j < ncols; ++j) {
  994.           // Here's the way you access the (i,j) element:
  995.           someFunction( matrix(i,j) );
  996.  
  997.           // You can safely "return" without any special delete code:
  998.           if (today == "Tuesday" && moon.isFull())
  999.             return;     // Quit early on Tuesdays when the moon is full
  1000.         }
  1001.       }
  1002.  
  1003.       // No explicit delete code at the end of the function either
  1004.     }
  1005.  
  1006. The main thing to notice is the lack of clean-up code.  For example, there
  1007. aren't any delete statements in the above code, yet there will be no memory
  1008. leaks, assuming only that the FredMatrix destructor does its job correctly.
  1009.  
  1010. Here's the FredMatrix code that makes the above possible:
  1011.  
  1012.     class FredMatrix {
  1013.     public:
  1014.       FredMatrix(unsigned nrows, unsigned ncols);
  1015.       // Throws a BadSize object if either size is zero
  1016.       class BadSize { };
  1017.  
  1018.       // Based on the Law Of The Big Three[25.8]:
  1019.      ~FredMatrix();
  1020.       FredMatrix(const FredMatrix& m);
  1021.       FredMatrix& operator= (const FredMatrix& m);
  1022.  
  1023.       // Access methods to get the (i,j) element:
  1024.       Fred&       operator() (unsigned i, unsigned j);
  1025.       const Fred& operator() (unsigned i, unsigned j) const;
  1026.       // These throw a BoundsViolation object if i or j is too big
  1027.       class BoundsViolation { };
  1028.  
  1029.     private:
  1030.       Fred* data_;
  1031.       unsigned nrows_, ncols_;
  1032.     };
  1033.  
  1034.     inline Fred& Matrix::operator() (unsigned row, unsigned col)
  1035.     {
  1036.       if (row >= nrows_ || col >= ncols_) throw BoundsViolation();
  1037.       return data_[row*ncols_ + col];
  1038.     }
  1039.  
  1040.     inline Fred Matrix::operator() (unsigned row, unsigned col) const
  1041.     {
  1042.       if (row >= nrows_ || col >= ncols_) throw BoundsViolation();
  1043.       return data_[row*ncols_ + col];
  1044.     }
  1045.  
  1046.     FredMatrix::FredMatrix(unsigned nrows, unsigned ncols)
  1047.       : data_  (new Fred[nrows * ncols]),
  1048.         nrows_ (nrows),
  1049.         ncols_ (ncols)
  1050.     {
  1051.       if (nrows == 0 || ncols == 0)
  1052.         throw BadSize();
  1053.     }
  1054.  
  1055.     Matrix::~Matrix()
  1056.     {
  1057.       delete[] data_;
  1058.     }
  1059.  
  1060. Note that the above FredMatrix class accomplishes two things: it moves some
  1061. tricky memory management code from the user code (e.g., main()) to the class,
  1062. and it reduces the overall bulk of program (e.g., assuming FredMatrix is even
  1063. mildly reusable, moving complexity from the users of FredMatrix into FredMatrix
  1064. itself is equivalent to moving complexity from the many to the few.  And anyone
  1065. who's seen Star Trek 3 knows that the good of the many outweighs the good of
  1066. the few... or the one.
  1067.  
  1068. ==============================================================================
  1069.  
  1070. [16.17] Does C++ have arrays whose length can be specified at run-time?
  1071.  
  1072. Yes, in the sense that STL[32.1] has a vector template that provides this
  1073. behavior.
  1074.  
  1075. No, in the sense that built-in array types need to have their length specified
  1076. at compile time.
  1077.  
  1078. Yes, in the sense that even built-in array types can specify the first index
  1079. bounds at run-time.  E.g., comparing with the previous FAQ, if you only need
  1080. the first array dimension to vary then you can just ask new for an array of
  1081. arrays, rather than an array of pointers to arrays:
  1082.  
  1083.     const unsigned ncols = 100;           // ncols = number of columns in the array
  1084.  
  1085.     class Fred { /*...*/ };
  1086.  
  1087.     void manipulateArray(unsigned nrows)  // nrows = number of rows in the array
  1088.     {
  1089.       Fred (*matrix)[ncols] = new Fred[nrows][ncols];
  1090.       // ...
  1091.       delete[] matrix;
  1092.     }
  1093.  
  1094. You can't do this if you need anything other than the first dimension of the
  1095. array to change at run-time.
  1096.  
  1097. But please, don't use arrays unless you have to.  Arrays are evil[21.5].  Use
  1098. some object of some class if you can.  Use arrays only when you have to.
  1099.  
  1100. ==============================================================================
  1101.  
  1102. [16.18] How can I force objects of my class to always be created via new rather
  1103.         than as locals or global/static objects?
  1104.  
  1105. Use the Named Constructor Idiom[10.6].
  1106.  
  1107. As usual with the Named Constructor Idiom, the constructors are all private: or
  1108. protected:, and there are one or more public static create() methods (the
  1109. so-called "named constructors"), one per constructor.  In this case the
  1110. create() methods allocate the objects via new.  Since the constructors
  1111. themselves are not public, there is no other way to create objects of the
  1112. class.
  1113.  
  1114.     class Fred {
  1115.     public:
  1116.       // The create() methods are the "named constructors":
  1117.       static Fred* create()                 { return new Fred();     }
  1118.       static Fred* create(int i)            { return new Fred(i);    }
  1119.       static Fred* create(const Fred& fred) { return new Fred(fred); }
  1120.       // ...
  1121.  
  1122.     private:
  1123.       // The constructors themselves are private or protected:
  1124.       Fred();
  1125.       Fred(int i);
  1126.       Fred(const Fred& fred);
  1127.       // ...
  1128.     };
  1129.  
  1130. Now the only way to create Fred objects is via Fred::create():
  1131.  
  1132.     main()
  1133.     {
  1134.       Fred* p = Fred::create(5);
  1135.       // ...
  1136.       delete p;
  1137.     }
  1138.  
  1139. Make sure your constructors are in the protected: section if you expect Fred to
  1140. have derived classes.
  1141.  
  1142. Note also that you can make another class Wilma a friend[14] of Fred if you
  1143. want to allow a Wilma to have a member object of class Fred, but of course this
  1144. is a softening of the original goal, namely to force Fred objects to be
  1145. allocated via new.
  1146.  
  1147. ==============================================================================
  1148.  
  1149. [16.19] How do I do simple reference counting?
  1150.  
  1151. If all you want is the ability to pass around a bunch of pointers to the same
  1152. object, with the feature that the object will automagically get deleted when
  1153. the last pointer to it disappears, you can use something like the following
  1154. "smart pointer" class:
  1155.  
  1156.     // Fred.h
  1157.  
  1158.     class FredPtr;
  1159.  
  1160.     class Fred {
  1161.     public:
  1162.       Fred() : count_(0) /*...*/ { }  // All ctors set count_ to 0 !
  1163.       // ...
  1164.     private:
  1165.       friend FredPtr;     // A friend class[14]
  1166.       unsigned count_;
  1167.       // count_ must be initialized to 0 by all constructors
  1168.       // count_ is the number of FredPtr objects that point at this
  1169.     };
  1170.  
  1171.     class FredPtr {
  1172.     public:
  1173.       Fred* operator-> () { return p_; }
  1174.       Fred& operator* ()  { return *p_; }
  1175.       FredPtr(Fred* p)    : p_(p) { }   // p must not be NULL
  1176.      ~FredPtr()           { if (--p_->count_ == 0) delete p_; }
  1177.       FredPtr(const FredPtr& p) : p_(p.p_) { ++p_->count_; }
  1178.       FredPtr& operator= (const FredPtr& p)
  1179.             { // DO NOT CHANGE THE ORDER OF THESE STATEMENTS!
  1180.               // (This order properly handles self-assignment[12.1])
  1181.               ++p.p_->count_;
  1182.               if (--p_->count_ == 0) delete p_;
  1183.               p_ = p.p_;
  1184.               return *this;
  1185.             }
  1186.     private:
  1187.       Fred* p_;    // p_ is never NULL
  1188.     };
  1189.  
  1190. Naturally you can use nested classes to rename FredPtr to Fred::Ptr.
  1191.  
  1192. Note that you can soften the "never NULL" rule above with a little more
  1193. checking in the copy constructor, assignment operator, and destructor.  If you
  1194. do that, you might as well put a p_ != NULL check into the "*" and "->"
  1195. operators (at least as an assert()).  I would recommend against an
  1196. operator Fred*() method, since that would let people accidentally get at the
  1197. Fred*.
  1198.  
  1199. If you want to be really safe, you can make all of Fred's constructors private,
  1200. and for each constructor have a public (static) create() method.  These
  1201. create() methods would return a FredPtr rather than a Fred*.  That way the only
  1202. way anyone could create a Fred object would be to get a FredPtr
  1203. ("Fred* p = new Fred()" would be replaced by "FredPtr p = Fred::create()").
  1204. Thus no one could accidentally subvert the reference counted mechanism by
  1205. saying getting a Fred*.  For example, if Fred had a Fred::Fred() and a
  1206. Fred::Fred(int i, int j), the changes to class Fred would be:
  1207.  
  1208.     class Fred {
  1209.     public:
  1210.       static FredPtr create()             { return new Fred(); }
  1211.       static FredPtr create(int i, int j) { return new Fred(i,j); }
  1212.       // ...
  1213.     private:
  1214.       Fred();
  1215.       Fred(int i, int j);
  1216.       // ...
  1217.     };
  1218.  
  1219. The end result is that you now have a way to use simple reference counting to
  1220. provide "pointer semantics" for a given object.  Users of your Fred class
  1221. explicitly use FredPtr objects, which act more or less like Fred* pointers.
  1222. The benefit is that users can make as many copies of their FredPtr "smart
  1223. pointer" objects, and the pointed-to Fred object will automagically get deleted
  1224. when the last such FredPtr object vanishes.
  1225.  
  1226. If you'd rather give your users "reference semantics" rather than "pointer
  1227. semantics," you can use reference counting to provide "copy on write"[16.20].
  1228.  
  1229. ==============================================================================
  1230.  
  1231. [16.20] How do I provide reference counting with copy-on-write semantics?
  1232.  
  1233. The previous FAQ[16.19] a simple reference counting scheme that provided users
  1234. with pointer semantics.  This FAQ describes an approach that provides users
  1235. with reference semantics.
  1236.  
  1237. The basic idea is to allow users to think they're copying your Fred objects,
  1238. but in reality the underlying implementation doesn't actually do any copying
  1239. unless and until some user actually tries to modify the underlying Fred object.
  1240.  
  1241. Class Fred::Data houses all the data that would normally go into the Fred
  1242. class.  Fred::Data also has an extra data member, count_, to manage the
  1243. reference counting.  Class Fred ends up being a "smart reference" that
  1244. (internally) points to a Fred::Data.
  1245.  
  1246.     class Fred {
  1247.     public:
  1248.  
  1249.       Fred();                               // A default constructor[10.4]
  1250.       Fred(int i, int j);                   // A normal constructor
  1251.  
  1252.       Fred(const Fred& f);
  1253.       Fred& operator= (const Fred& f);
  1254.      ~Fred();
  1255.  
  1256.       void sampleInspectorMethod() const;   // No changes to this object
  1257.       void sampleMutatorMethod();           // Change this object
  1258.  
  1259.       // ...
  1260.  
  1261.     private:
  1262.  
  1263.       class Data {
  1264.       public:
  1265.         Data();
  1266.         Data(int i, int j);
  1267.  
  1268.         // Since only Fred can access a Fred::Data object,
  1269.         // you can make Fred::Data's data public if you want.
  1270.         // But if that makes you uncomfortable, make the data private
  1271.         // and make Fred a friend class[14] via friend Fred;
  1272.         // ...
  1273.  
  1274.         unsigned count_;
  1275.         // count_ must be initialized to 0 by all constructors
  1276.         // count_ is the number of Fred objects that point at this
  1277.       };
  1278.  
  1279.       Data* data_;
  1280.     };
  1281.  
  1282.     Fred::Data::Data()             : count_(1) /*init other data*/ { }
  1283.     Fred::Data::Data(int i, int j) : count_(1) /*init other data*/ { }
  1284.  
  1285.     Fred::Fred()             : data_(new Data()) { }
  1286.     Fred::Fred(int i, int j) : data_(new Data(i, j)) { }
  1287.  
  1288.     Fred::Fred(const Fred& f)
  1289.       : data_(f.data_)
  1290.     {
  1291.       ++ data_->count_;
  1292.     }
  1293.  
  1294.     Fred& Fred::operator= (const Fred& f)
  1295.     {
  1296.       // DO NOT CHANGE THE ORDER OF THESE STATEMENTS!
  1297.       // (This order properly handles self-assignment[12.1])
  1298.       ++ f.data_->count_;
  1299.       if (--data_->count_ == 0) delete data_;
  1300.       data_ = f.data_;
  1301.       return *this;
  1302.     }
  1303.  
  1304.     Fred::~Fred()
  1305.     {
  1306.       if (--data_->count_ == 0) delete data_;
  1307.     }
  1308.  
  1309.     void Fred::sampleInspectorMethod() const
  1310.     {
  1311.       // This method promises ("const") not to change anything in *data_
  1312.       // Other than that, any data access would simply use "data_->..."
  1313.     }
  1314.  
  1315.     void Fred::sampleMutatorMethod()
  1316.     {
  1317.       // This method might need to change things in *data_
  1318.       // Thus it first checks if this is the only pointer to *data_
  1319.       if (data_->counter > 1) {
  1320.         Data* d = new Data(*data_);    // Invoke Fred::Data's copy ctor
  1321.         -- data_->counter_;
  1322.         data_ = d;
  1323.       }
  1324.       assert(data_->counter_ == 1);
  1325.  
  1326.       // Now the method proceeds to access "data_->..." as normal
  1327.     }
  1328.  
  1329. If it is fairly common to call Fred's default constructor[10.4], you can avoid
  1330. all those new calls by sharing a common Fred::Data object for all Freds that
  1331. are constructed via Fred::Fred().  To avoid static initialization order
  1332. problems, this shared Fred::Data object is created "on first use" inside a
  1333. function.  Here are the changes that would be made to the above code (note that
  1334. the shared Fred::Data object's destructor is never invoked; if that is a
  1335. problem, either hope you don't have any static initialization order problems,
  1336. or drop back to the approach described above):
  1337.  
  1338.     class Fred {
  1339.     public:
  1340.       // ...
  1341.     private:
  1342.       // ...
  1343.       static Data* defaultData();
  1344.     };
  1345.  
  1346.     Fred::Fred() : data_(defaultData()) { }
  1347.  
  1348.     Fred::Data* Fred::defaultData()
  1349.     {
  1350.       static Data* p = NULL;
  1351.       if (p == NULL) {
  1352.         p = new Data();
  1353.         ++ p->count_;    // Make sure it never goes to zero
  1354.       }
  1355.       return p;
  1356.     }
  1357.  
  1358. Note: You can also provide reference counting for a hierarchy of classes[16.21]
  1359. if your Fred class would normally have been a base class.
  1360.  
  1361. ==============================================================================
  1362.  
  1363. [16.21] How do I provide reference counting with copy-on-write semantics for a
  1364.         hierarchy of classes?
  1365.  
  1366. The previous FAQ[16.20] presented a reference counting scheme that provided
  1367. users with reference semantics, but did so for a single class rather than for a
  1368. hierarchy of classes.  This FAQ extends the previous technique to allow for a
  1369. hierarchy of classes.  The basic difference is that Fred::Data is now the root
  1370. of a hierarchy of classes, which probably cause it to have some virtual[20]
  1371. functions.  Note that class Fred itself will still not have any virtual
  1372. functions.
  1373.  
  1374. The Virtual Constructor Idiom[20.5] is used to make copies of the Fred::Data
  1375. objects.  To select which derived class to create, the sample code below uses
  1376. the Named Constructor Idiom[10.6], but other techniques are possible (a switch
  1377. statement in the constructor, etc).  The sample code assumes two derived
  1378. classes: Der1 and Der2.  Methods in the derived classes are unaware of the
  1379. reference counting.
  1380.  
  1381.     class Fred {
  1382.     public:
  1383.  
  1384.       static Fred create1(String s, int i);
  1385.       static Fred create2(float x, float y);
  1386.  
  1387.       Fred(const Fred& f);
  1388.       Fred& operator= (const Fred& f);
  1389.      ~Fred();
  1390.  
  1391.       void sampleInspectorMethod() const;   // No changes to this object
  1392.       void sampleMutatorMethod();           // Change this object
  1393.  
  1394.       // ...
  1395.  
  1396.     private:
  1397.  
  1398.       class Data {
  1399.       public:
  1400.         Data() : count_(1) { }
  1401.         virtual ~Data() { }                              // A virtual destructor[20.4]
  1402.         virtual Data* clone() const = 0;                 // A virtual constructor[20.5]
  1403.         virtual void sampleInspectorMethod() const = 0;  // A pure virtual function[22.4]
  1404.         virtual void sampleMutatorMethod() = 0;
  1405.       private:
  1406.         unsigned count_;   // count_ doesn't need to be protected
  1407.       };
  1408.  
  1409.       class Der1 : public Data {
  1410.       public:
  1411.         Der1(String s, int i);
  1412.         virtual void sampleInspectorMethod() const;
  1413.         virtual void sampleMutatorMethod();
  1414.         virtual Data* clone() const;
  1415.         // ...
  1416.       };
  1417.  
  1418.       class Der2 : public Data {
  1419.       public:
  1420.         Der2(float x, float y);
  1421.         virtual void sampleInspectorMethod() const;
  1422.         virtual void sampleMutatorMethod();
  1423.         virtual Data* clone() const;
  1424.         // ...
  1425.       };
  1426.  
  1427.       Fred(Data* data);
  1428.       // Creates a Fred smart-reference that owns *data
  1429.       // It is private to force users to use a createXXX() method
  1430.       // Requirement: data must not be NULL
  1431.  
  1432.       Data* data_;   // Invariant: data_ is never NULL
  1433.     };
  1434.  
  1435.     Fred::Fred(Data* data) : data_(data)  { assert(data != NULL); }
  1436.  
  1437.     Fred Fred::create1(String s, int i)   { return Fred(new Der1(s, i)); }
  1438.     Fred Fred::create2(float x, float y)  { return Fred(new Der2(x, y)); }
  1439.  
  1440.     Fred::Data* Fred::Der1::clone() const { return new Der1(*this); }
  1441.     Fred::Data* Fred::Der2::clone() const { return new Der2(*this); }
  1442.  
  1443.     Fred::Fred(const Fred& f)
  1444.       : data_(f.data_)
  1445.     {
  1446.       ++ data_->count_;
  1447.     }
  1448.  
  1449.     Fred& Fred::operator= (const Fred& f)
  1450.     {
  1451.       // DO NOT CHANGE THE ORDER OF THESE STATEMENTS!
  1452.       // (This order properly handles self-assignment[12.1])
  1453.       ++ f.data_->count_;
  1454.       if (--data_->count_ == 0) delete data_;
  1455.       data_ = f.data_;
  1456.       return *this;
  1457.     }
  1458.  
  1459.     Fred::~Fred()
  1460.     {
  1461.       if (--data_->count_ == 0) delete data_;
  1462.     }
  1463.  
  1464.     void Fred::sampleInspectorMethod() const
  1465.     {
  1466.       // This method promises ("const") not to change anything in *data_
  1467.       // Therefore we simply "pass the method through" to *data_:
  1468.       data_->sampleInspectorMethod();
  1469.     }
  1470.  
  1471.     void Fred::sampleMutatorMethod()
  1472.     {
  1473.       // This method might need to change things in *data_
  1474.       // Thus it first checks if this is the only pointer to *data_
  1475.       if (data_->counter > 1) {
  1476.         Data* d = data_->clone();   // The Virtual Constructor Idiom[20.5]
  1477.         -- data_->counter_;
  1478.         data_ = d;
  1479.       }
  1480.       assert(data_->counter_ == 1);
  1481.  
  1482.       // Now we "pass the method through" to *data_:
  1483.       data_->sampleInspectorMethod();
  1484.     }
  1485.  
  1486. Naturally the constructors and sampleXXX methods for Fred::Der1 and Fred::Der2
  1487. will need to be implemented in whatever way is appropriate.
  1488.  
  1489. ==============================================================================
  1490.  
  1491.